; ==========================================================
; pmt.inc - protect model include
; 用于定义保护模式中的一些常量、宏，以及一些说明
; ==========================================================

; =========================================
; FLAGS - Intel 8086 Family Flags Register
; =========================================
;
;      |11|10|F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0|
;        |  | | | | | | | | | | | | | | | | '---  CF……Carry Flag
;        |  | | | | | | | | | | | | | | | '---  1
;        |  | | | | | | | | | | | | | | '---  PF……Parity Flag
;        |  | | | | | | | | | | | | | '---  0
;        |  | | | | | | | | | | | | '---  AF……Auxiliary Flag
;        |  | | | | | | | | | | | '---  0
;        |  | | | | | | | | | | '---  ZF……Zero Flag
;        |  | | | | | | | | | '---  SF……Sign Flag
;        |  | | | | | | | | '---  TF……Trap Flag  (Single Step)
;        |  | | | | | | | '---  IF……Interrupt Flag
;        |  | | | | | | '---  DF……Direction Flag
;        |  | | | | | '---  OF……Overflow flag
;        |  | | | '-----  IOPL……I/O Privilege Level  (286+ only)
;        |  | | '-----  NT……Nested Task Flag  (286+ only)
;        |  | '-----  0
;        |  '-----  RF……Resume Flag (386+ only)
;        '------  VM……Virtual Mode Flag (386+ only)
;
;        注: see   PUSHF  POPF  STI  CLI  STD  CLD
;

;-----------------------------------------------------------
; 描述符类型值说明
; 其中:
;       DA_  : Descriptor Attribute
;       D    : 数据段
;       C    : 代码段
;       S    : 系统段
;       R    : 只读
;       RW   : 读写
;       A    : 已访问
;       其它 : 可按照字面意思理解
;-----------------------------------------------------------

; equ用于定义符号常量，类似c语言中的define。
; D/B 可执行代码段为D位 还有两种情况为B位，遇到再注明
; D/B 位于描述符的BYTE6的bit6
; D: 1-默认情况下，指令使用32位地址及32位或8位操作数
; D: 0-默认情况下，指令使用16位地址及16位或8位操作数
; 4000h:0100 0000 0000 0000 D位为1
DA_32       EQU 4000h   ; 32 位段 
DA_LIMIT_4K	EQU	8000h	; 段界限粒度为 4K 字节

; DPL：表示描述符特权级(Descriptor Privilege level)，共2位。
; 它规定了所描述段的特权级，用于特权检查，以决定对该段能否访问。
; DPL 位于描述符的BYTE5的bit5、6 
DA_DPL0     EQU 00h     ; DPL = 0 00h:0000 0000
DA_DPL1     EQU 20h     ; DPL = 1 20h:0010 0000
DA_DPL2     EQU 40h     ; DPL = 2 40h:0100 0000
DA_DPL3     EQU 60h     ; DPL = 3 60h:0110 0000

; 存储段描述符类型值说明
; 存在位P 位于描述符的BYTE5的bit7 P：1-段在内存中存在 0-不存在 
; 说明的描述符类型S 位于描述符的BYTE5的bit4 
; S: 1-数据段和代码段 0-系统段和门描述符
; 描述符类型TYPE 位于描述符的BYTE5的bit0、1、2、3
; 90h:1001 0000 P为1 S为1 TYPE为0000
DA_DR		EQU	90h	; 存在的只读数据段类型值
DA_DRW		EQU	92h	; 存在的可读写数据段属性值
DA_DRWA		EQU	93h	; 存在的已访问可读写数据段类型值
DA_C		EQU	98h	; 存在的只执行代码段属性值
DA_CR		EQU	9Ah	; 存在的可执行可读代码段属性值
DA_CCO		EQU	9Ch	; 存在的只执行一致代码段属性值
DA_CCOR		EQU	9Eh	; 存在的可执行可读一致代码段属性值

; 系统段描述符类型值说明
; 82h:1000 0010 P为1 S为0 TYPE为0010
DA_LDT		EQU	  82h	; 局部描述符表段类型值
DA_TaskGate	EQU	  85h	; 任务门类型值
DA_386TSS	EQU	  89h	; 可用 386 任务状态段类型值
DA_386CGate	EQU	  8Ch	; 386 调用门类型值
DA_386IGate	EQU	  8Eh	; 386 中断门类型值
DA_386TGate	EQU	  8Fh	; 386 陷阱门类型值

;-----------------------------------------------------------
; 选择子类型值说明
; 其中:
;       SA_  : Selector Attribute
;-----------------------------------------------------------

; RPL(Request Privilege level):表示对段访问的请求特权级，共2位。
; RPL 位于段选择子的bit0、1 
SA_RPL0		EQU	0	
SA_RPL1		EQU	1	
SA_RPL2		EQU	2	 
SA_RPL3		EQU	3	 

; TI 位于段选择子的bit3
SA_TIG		EQU	0	; TI位为0 查GDT表
SA_TIL		EQU	4	; TI位为1 查LDT表

;----------------------------------------------------------------------------
; 分页机制使用的常量说明
;----------------------------------------------------------------------------
PG_P		EQU	1	; 页存在属性位
PG_RWR		EQU	0	; R/W 属性位值, 读/执行
PG_RWW		EQU	2	; R/W 属性位值, 读/写/执行
PG_USS		EQU	0	; U/S 属性位值, 系统级
PG_USU		EQU	4	; U/S 属性位值, 用户级

;-----------------------------------------------------------
; 宏
; 描述符
; usage: Descriptor Base, Limit, Attr
;        Base:  dd 4字节(段基址1:BYTE2、3、4; 2:BYTE7)
;        Limit: dd (段界限1:BYTE0、1; 2:BYTE6 bit0、1、2、3)
;               所以Limit其实只要低20位有效
;        Attr:  dW 2字节(BYTE5、6，但要排除段界限2)
;               所以只有bit0~7(属性1)，bit12~15(属性2)有效
;-----------------------------------------------------------
; %macro %endmacro 用于定义一个多行宏
; 3代表有3个参数 %1表示第一个参数 以此类推
%macro Descriptor 3
	dw	%2 & 0FFFFh ; 取第二个参数的低16位作为宏的第0、1字节(段界限1)
	dw	%1 & 0FFFFh ; 取第一个参数的低16位作为宏的第2、3字节(段基址1的BYTE2、3)
	db	(%1 >> 16) & 0FFh   ; 取第一个参数的第2个字节作为宏的第4个字节(段基址1的BYTE4)
	dw	((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)	
        ; 将第三个参数的bit8~11置为0
        ; 将第二个参数的bit16~19保留，其余置为宏的第5、6个字节(属性1+段界限2+属性2)
        ; 将上诉两个数取或 得到2个字节 作为
	db	(%1 >> 24) & 0FFh   ; 取第一个参数高8位作为宏的第7个字节(段基址2)
%endmacro ; 共 8 字节

; 门，结构与段描述符类似，该宏也与 Descriptor 类似
; usage: Gate Selector, Offset, DCount, Attr
;        Selector:  dw
;        Offset:    dd
;        DCount:    db
;        Attr:      db
%macro Gate 4
	dw	(%2 & 0FFFFh)						; 偏移 1				(2 字节)
	dw	%1									; 选择子				(2 字节)
	dw	(%3 & 1Fh) | ((%4 << 8) & 0FF00h)	; 属性					(2 字节)
	dw	((%2 >> 16) & 0FFFFh)				; 偏移 2				(2 字节)
%endmacro ; 共 8 字节